package mspbots.cw.business.core.schedule;

import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import mspbots.cw.business.core.BaseReceiver;
import mspbots.cw.business.core.subdata.SubdataRepository;
import mspbots.cw.common.ResultMsg;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.time.Duration;

/**
 * @author Jay.Yang
 */
@Log4j2
@Component
@RequiredArgsConstructor
public class ScheduleReceiver extends BaseReceiver {

    private final ScheduleRepository scheduleRepository;
    private final SubdataRepository subdataRepository;

    @RabbitListener(queues = "connect-wise.schedules.tl", concurrency = "8")
    public void process(ResultMsg resultMsg) {
        if ("deleted".equals(resultMsg.getAction())) {
            this.scheduleRepository.deleteById(resultMsg.getId()).block(Duration.ofSeconds(10));
            return;
        }

        JsonNode entity = resultMsg.getEntity();
        Schedule data = super.objectMapper.convertValue(entity, Schedule.class);
        data.setId(null);
        data.setCwId(resultMsg.getId());
        data.setTenantCode(resultMsg.getTenantId());
        data.setSyncTime(resultMsg.getSyncDate());

        data.setTicketId(super.getLongValue(entity.get("objectId")));
        data.setDateEntered(super.getDateTimeValue(entity.findValue("dateEntered")));
        data.setIdentifier(super.getStringValueIdentifier(entity.get("member")));
        data.setCwUid(super.getLongValueId(entity.get("member")));
        data.setMemberName(super.getStringValueName(entity.get("member")));

        if (!ObjectUtils.isEmpty(entity.get("type"))) {
            data.setTypeId(super.getLongValueId(entity.get("type")));
            subdataRepository.findByCwIdAndApiTypeAndTenantCode(data.getTypeId(), "SCHEDULE-TYPE", resultMsg.getTenantId())
                    .map(result -> {
                        data.setTypeName(result.getName());
                        return data;
                    }).block(Duration.ofSeconds(10));
        }

        this.scheduleRepository.findByCwIdAndTenantCode(resultMsg.getId(), resultMsg.getTenantId())
                .map(result -> {
                    data.setId(result.getId());
                    return data;
                })
                .defaultIfEmpty(data)
                .flatMap(this.scheduleRepository::save).block(Duration.ofSeconds(10));
    }

}
